Ext.define('Ext.ux.DwrProxy', {
    requires: ['Ext.util.MixedCollection'],
    extend: 'Ext.data.proxy.Server',
    alias: 'proxy.dwr',
    alternateClassName: ['Ext.data.dwrProxy'],

    /**
     * @property actionMethods
     * Mapping of action name to HTTP request method. In the basic AjaxProxy these are set to 'GET' for 'read' actions and 'POST'
     * for 'create', 'update' and 'destroy' actions. The {@link Ext.data.proxy.Rest} maps these to the correct RESTful methods.
     */
    actionMethods: {
        create : 'POST',
        read   : 'GET',
        update : 'POST',
        destroy: 'POST'
    },

    /**
     * @cfg {Object} headers Any headers to add to the Ajax request. Defaults to <tt>undefined</tt>.
     */

    /**
     * @ignore
     */
    constructor    : function(config){
        this.url = 'www.baidu.com';
        this.superclass.constructor.call(this, config);
    },
    doRequest: function(operation, callback, scope) {
        var me = this;
        var writer  = this.getWriter(),
        request = this.buildRequest(operation, callback, scope);

        if (operation.allowWrite()) {
            request = writer.write(request);
        }
        
        Ext.apply(request, {
            headers       : this.headers,
            timeout       : this.timeout,
            scope         : this,
            callback      : this.createRequestCallback(request, operation, callback, scope),
            method        : this.getMethod(request),
            disableCaching: false // explicitly set it to false, ServerProxy handles caching
        });

        //creating param list that is going to be sent to Dwr.
        //and adding the request.param as the first parameter
        var dwrParams = [request.params];

        ///adding parameters if there are defined any in proxy configuration
        
        if(typeof(me.dwrParams)==='object'){
            dwrParams = dwrParams.concat(me.dwrParams);
        };
        //adding callback function
        dwrParams.push(
            function(x){
                me.processResponse(true, operation, request, x, callback, scope);
            });

        ///making a call
        me.dwrFunction.apply(null,dwrParams);
           
  
        return request;
    },

    /**
     * Returns the HTTP method name for a given request. By default this returns based on a lookup on {@link #actionMethods}.
     * @param {Ext.data.Request} request The request object
     * @return {String} The HTTP method to use (should be one of 'GET', 'POST', 'PUT' or 'DELETE')
     */
    getMethod: function(request) {
        return this.actionMethods[request.action];
    },

    /**
     * @private
     * TODO: This is currently identical to the JsonPProxy version except for the return function's signature. There is a lot
     * of code duplication inside the returned function so we need to find a way to DRY this up.
     * @param {Ext.data.Request} request The Request object
     * @param {Ext.data.Operation} operation The Operation being executed
     * @param {Function} callback The callback function to be called when the request completes. This is usually the callback
     * passed to doRequest
     * @param {Object} scope The scope in which to execute the callback function
     * @return {Function} The callback function
     */
    createRequestCallback: function(request, operation, callback, scope) {
        
        var me = this;
        
        return  function(options, success, response) {
            me.processResponse(success, operation, request, response, callback, scope);
        };
    },
    processResponse: function(success, operation, request, response, callback, scope){
        //console.log(response);
        //me.extractResponseData(response);
        var me = this,
        reader,
        result = {},
        records,
        length,
        mc,
        record,
        i;
        
        if (success === true) {
            reader = me.getReader();
            //console.log(reader.totalProperty,reader.root);
            var data = {};
            data[reader.totalProperty] = response[reader.totalProperty] || response.totalCount;
            data[reader.root] = response[reader.root] || response.root;
            result = reader.readRecords(data);
            
            records = result.records;
            length = records.length;
            //console.log(result);
            if (result.success !== false) {
                mc = Ext.create('Ext.util.MixedCollection', true, function(r) {
                    return r.getId();
                });
                mc.addAll(operation.records);
                for (i = 0; i < length; i++) {
                    record = mc.get(records[i].getId());
                    //console.log(records[i].getId());
                    if (record) {
                        //console.log(1);
                        record.beginEdit();
                        record.set(record.data);
                        record.endEdit(true);
                    }
                }

                //see comment in buildRequest for why we include the response object here
                Ext.apply(operation, {
                    response: response,
                    resultSet: result
                });

                operation.setCompleted();
                operation.setSuccessful();
            } else {
                operation.setException(result.message);
                me.fireEvent('exception', this, response, operation);
            }
        } else {
            me.setException(operation, response);
            me.fireEvent('exception', this, response, operation);
        }

        //this callback is the one that was passed to the 'read' or 'write' function above
        if (typeof callback == 'function') {
            callback.call(scope || me, operation);
        }

        me.afterRequest(request, success);
    }
}, function() {
    //backwards compatibility, remove in Ext JS 5.0
    Ext.data.HttpProxy = this;
});

